// pub trait  Summary{
//     fn summarize(&self)->String;
// }

use std::fmt::{Display, Debug};


//trait默认方法
pub trait  Summary{
    fn summarize_author(&self)->String;
    fn summarize(&self)->String{
        // String::from("read more...",self.summarize())
        format!("(test  {})", self.summarize_author())
    }
}
pub struct NewsArticle{
    pub headline:String,
    pub location:String,
    pub author:String,
    pub content:String,
}

//使用trait作为参数
//在notify的函数体内，我们可以调用来自Summary trait的任何方法，
pub fn notify(item:impl Summary){
    println!("this is trait 作为参数{}",item.summarize());
}
//trait约束   trait约束（traitbound）的一种语法糖
//完整形式如下
pub fn notifyBound<T:Summary>(item:T){
    println!("this is trait 作为参数{}",item.summarize());
}
//多个trait的参数写法如下 只要item1和item2可以使用不同的类型（同时都实现了Summary）
pub fn notifyOne(item1:impl Summary,item2:impl Summary){}
//如果你想强迫两个参数使用同样的类型  泛型T指定了参数item1与item2的类型，它同时也决定了函数为item1与item2接收的参数值必须拥有相同的类型。
pub fn notifyBoundOne<T:Summary>(item1:T,item2:T){}
//通过+语法来指定多个trait约束
//假如notify函数需要在调用summarize方法的同时显示格式化后的item，那么item就必须实现两个不同的trait：Summary和Display。
pub fn notifyTwo(item:impl Summary+Display){}
pub fn notifyTwo2<T:Summary+Display>(item:T){}
//使用where从句来简化trait约束
// 使用过多的trait约束也有一些缺点。因为每个泛型都拥有自己的trait约束，定义有多个泛型参数的函数可能会有大量的trait约束
// 信息需要被填写在函数名与参数列表之间。这往往会使函数签名变得难以理解。为了解决这一问题，Rust提供了一个替代语法，
// 使我们可以在函数签名之后使用where从句来指定trait约束.
fn  notify_where<T:Display+Clone,U:Clone+Debug>(t:T,u:U)->i32{3}
//使用where 时的函数签名就没有那么杂乱了。函数名、参数列表及返回类型的排布要紧密得多，与没有trait约束的函数相差无几。
fn  some_function<T,U>(t:T,u:U)->i32
    where T:Display+Clone,U:Clone+Debug{4}


// 返回实现了trait的类型
fn returns_summarizable()->impl Summary{
    Tweet{
        username:String::from("test 返回实现trait"),
        content:String::from("test "),
        reply:true,
        retreat:false,
    }
}
//只能在返回一个类型时使用impl Trait。下面这段代码中返回的NewsArticle和Tweet都实现了impl Summary，却依然无法通过编译：
//试返回NewsArticle或Tweet类型，但碍于impl Trait工作方式的限制，Rust并不支持这样的写法。
// fn returns_summarizable_one(switch:bool)->impl Summary{
    // if switch {
    //     NewsArticle{
    //         headline:String::from("34"),
    //         location:String::from("2"),
    //         author:String::from("3"),
    //         content:String::from("4"),
    //     }
    // }else {
    //     Tweet{
    //         username:String::from("test 返回实现trait"),
    //         content:String::from("test "),
    //         reply:false,
    //         retreat:false,
    //     }
    // }
// }

// 使用trait约束来修复largest函数


// impl Summary for NewsArticle {}

impl Summary for NewsArticle {
    fn summarize_author(&self)->String{
        format!("@{}",self.headline)
    }
    // fn summarize(&self)->String{
    //     format!("{} , by {} ({})",self.headline,self.author,self.location)
    // }
}
pub struct Tweet{
    pub username:String,
    pub content:String,
    pub reply:bool,
    pub retreat:bool,
}
impl Summary for Tweet {
    fn summarize_author(&self)->String{
        format!("@{}",self.username)
    }
}


// impl Summary for Tweet {
//     fn summarize(&self)->String{
//         format!("{},{}",self.username,self.content)
//     }
// }

// impl Summary for Tweet {
//     fn summarize_author(&self)->String{
//         String::from("1123")
//     }
//     fn summarize(&self)->String{
//         format!("{},{}",self.username,self.content)
//     }
// }